extern crate nalgebra as na;
use na::*;
use rand::thread_rng;
use rand_distr::{Distribution, Normal, NormalError};
use rayon::prelude::*;
use std::cmp;
include!("heston.rs");
include!("jump_dif.rs");
include!("sqrt_dif.rs");
extern crate docify;
pub trait Stochastic {
    fn gen_path(&self) -> Vec<f64>;
}

pub struct GeoBrown {
    pub S0: f64,
    pub T: f64,
    pub steps: usize,
    pub sigma: f64,
    pub mu: f64,
}
/// 价格服从对数正态,收益率服从正态分布 https://zhuanlan.zhihu.com/p/407347892
impl GeoBrown {
    pub fn simulate_return(&self) -> Vec<f64> {
        let mut rng = rand::thread_rng();
        let normal = Normal::new(0.0, 1.0).unwrap();

        let dt = self.T / (self.steps as f64);
        // let item1 = (self.r - self.divdend - sigma.powf(2.0) / 2.0) * dt;

        let mut res = Vec::new();

        for i in 0..self.steps {
            let z = normal.sample(&mut rng);
            let simu = self.mu * dt + z * self.sigma * dt.sqrt();
            res.push(simu)
        }
        res
    }
}
impl Stochastic for GeoBrown {
    fn gen_path(&self) -> Vec<f64> {
        let rate = self.simulate_return();
        let mut res = Vec::new();
        let mut cur = self.S0;
        // r 不是年化,已近含有dt
        for r in rate {
            cur = cur * r.exp();
            res.push(cur);
        }
        res
    }
}
